#include "measure.h"
#include "sql.h"
#include "settings.h"
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <unistd.h>

Measure::Measure(Settings *setting, SQL *sql)
    : mSetting(setting),
      mSql(sql)
{
}

Measure::~Measure() {
}

unsigned short Measure::sensorRead(int fileD) {
    int r = 0, uSleep = 60000, readSleep = 200;
    unsigned char value[2];
    unsigned short sensorValue;

    usleep(uSleep);

    while (r < 1) {
        usleep(readSleep);
        r = read(fileD, &value[0], 2);
    }

    sensorValue = value[0] << 8;
    sensorValue = sensorValue | (value[1] & 0xfc);

    return sensorValue;
}

void Measure::sensorWrite(int fileD, unsigned short command) {
    int r = 0, writeSleep = 300;

    while (r < 1) {
        usleep(writeSleep);
        r = write(fileD, &command, 1);
    }
}

void Measure::measureAll() {
    int  fd;
    bool boolTemp, boolHumi, boolDb;

    boolTemp        =   mSetting->getTempInfo();
    boolHumi        =   mSetting->getHumiInfo();
    boolDb          =   mSetting->getDB();

    fd = openDev();

    if (boolTemp) {
        int cmdTemp, intCalcTemp;
        unsigned short temp;
        float calcTemp;

        cmdTemp = mSql->getTempCommand().toInt(0, 16);

        // Temperatur auslesen
        sensorWrite(fd, cmdTemp);
        temp = sensorRead(fd);


        // Berechnung Temperatur
        calcTemp = (-46.85) + (175.72 * (temp / 65536.0));
        calcTemp = decimalPlaces(intCalcTemp, calcTemp);


        //Datenbank schreiben
        if (boolDb)
            mSql->insertValue(calcTemp, "Temperatur");


        if (boolHumi)
            qDebug() << "Temperatur:" << calcTemp << "°C";
        else
            qDebug() << "Temperatur:" << calcTemp << "°C\n";
    }

    if (boolHumi) {
        int cmdHumi, intCalcHumi;
        unsigned short humidity;
        float calcHumidity;

        cmdHumi = mSql->getHumiCommand().toInt(0, 16);

        // Feuchtigkeit auslesen
        sensorWrite(fd, cmdHumi);
        humidity = sensorRead(fd);


        //Berechnung Feuchtigkeit
        calcHumidity = (-6) + (125 * (humidity / 65536.0));
        calcHumidity = decimalPlaces(intCalcHumi, calcHumidity);


        //Datenbank schreiben
        if (boolDb)
            mSql->insertValue(calcHumidity, "Feuchtigkeit");


        qDebug() << "Feuchtigkeit:" << calcHumidity << "%\n";
    }
}

double Measure::decimalPlaces(int intMeasure, double value) {
    value = value * 100 + 0.5;
    intMeasure = value;
    value = intMeasure;

    value /= 100;

    return value;
}

int Measure::openDev() {
    QString stringAdr;
    QString stringDriver;
    QByteArray byteDriver;

    const char *devDriver;
    int r = 0, fd, intAdr;

    stringDriver = mSql->getDriver();
    byteDriver = stringDriver.toLatin1();
    devDriver = byteDriver.data();

    stringAdr = mSql->getAddress();
    intAdr = stringAdr.toInt(0, 16);


    fd = open(devDriver, O_RDWR);
    if (fd < 0)
        printf("Open Failed!");

    r = ioctl(fd, I2C_SLAVE, intAdr);
    if (r < 0)
        printf("setting address failed!");

    return fd;
}
